package im.yisme.model;

import java.io.IOException;
import java.util.ArrayList;
import java.util.Iterator;

import android.util.Log;
import android.view.MotionEvent;

import im.yisme.model.fileio.LyricsWriter;
import im.yisme.model.record.PackagedRecordAction;
import im.yisme.model.record.StatusMachine;
import im.yisme.model.service.LyricsRepositoryService;
import im.yisme.model.service.ModelServiceProvider;
import im.yisme.model.service.RecordSystemService;
import im.yisme.vo.LyricsVO;
import im.yisme.vo.MusicVO;
import im.yisme.vo.RawActionVO;
import im.yisme.vo.InputResultVO;


public class RecordSystem implements RecordSystemService{

	private static RecordSystem recordSystem;
	private LyricsRepositoryService lyricsRepositoryService;
	private MusicVO recordingMusic;
	private LyricsVO recordingLyrics;

	private LyricsHeader header;
	private ArrayList<LyricsAction> finishedLyricsAction;
	private Lyrics recordedLyrics;
	
    private ArrayList<PackagedRecordAction> pActionList;
	private boolean reverse,twoPointer;
	
	
	private RecordSystem(){
		init();
	}
	
	public static RecordSystem getInstance(){
		return recordSystem == null ? recordSystem = new RecordSystem() : recordSystem;
	}
	
	public MusicVO getRecordingMusic() {
		return recordingMusic;
	}
	public void setRecordingMusic(MusicVO recordingMusic) {
		this.recordingMusic = recordingMusic;
	}
	public LyricsVO getRecordingLyrics() {
		return recordingLyrics;
	}
	public void setRecordingLyrics(LyricsVO recordingLyrics) {
		this.recordingLyrics = recordingLyrics;
	}
	public LyricsVO getRecordedLyrics(){
		return new LyricsVO(recordedLyrics);
	}

	public void loadResource() {
		// TODO Auto-generated method stub
		
	}
	public void startRecord() {
		// TODO Auto-generated method stub
		
	}
    public void finishRecord() {
    	header=new LyricsHeader(0 , 0, false, false);
		recordedLyrics=new Lyrics(0, recordingMusic.getArtist(), recordingMusic.getName(), "",Lyrics.ORIGINAL);
		recordedLyrics.setLyricsHeader(header);
		recordedLyrics.setLyricsActions(finishedLyricsAction);
		recordedLyrics.setNoteNum(finishedLyricsAction.size());	
		recordedLyrics.setTotalTime(recordingMusic.getDuration());
		
		for(int i=0;i<finishedLyricsAction.size();i++){
			Log.i("RecordSystem", finishedLyricsAction.get(i).toString());
			Log.i("RecordSystem", "--------------------------------------");
		}
		
		lyricsRepositoryService = ModelServiceProvider.getLyricsRepositoryService();
		lyricsRepositoryService.loadFile();
		long id = lyricsRepositoryService.addLyricsToRepository(recordedLyrics.toVO());
		
		recordedLyrics.setId(id);
		saveLyricsInfo(recordedLyrics);
    }
	
	public InputResultVO handleInput(RawActionVO action) {
		// TODO Auto-generated method stub
		InputResultVO resultVO = new InputResultVO(action.getAction(), false);
		
		int moment = action.getMoment();
		
		switch (action.getAction()) {
		case RawActionVO.DOWN:
			Log.i("RecordSystem", "down");
			PackagedRecordAction newAction = new PackagedRecordAction(action.getMoment());
			newAction.addAction(action.getAction(), action.x1, action.y1, moment);
			
			pActionList.add(newAction);
			
			break;
		case RawActionVO.MOVE:
			
			if(pActionList.size() == 1){
				Log.i("RecordSystem", "move1");
				PackagedRecordAction oriAction = pActionList.get(0);
				oriAction.addAction(action.getAction(), action.x1, action.y1, moment);
			}
			else {
				Log.i("RecordSystem", "move2");
				PackagedRecordAction oriAction1 = pActionList.get(0);
				PackagedRecordAction oriAction2 = pActionList.get(1);
				
				if(twoPointer){
					if(reverse){
						oriAction1.addAction(action.getAction(), action.x2, action.y2, moment);
						oriAction2.addAction(action.getAction(), action.x1, action.y1, moment);

					}
					else {
						oriAction1.addAction(action.getAction(), action.x1, action.y1, moment);
						oriAction2.addAction(action.getAction(), action.x2, action.y2, moment);
					}
				}
				else {
	
					float distance11 = oriAction1.getDistance(action.x1, action.y1);
					float distance21 = oriAction1.getDistance(action.x2, action.y2);
					
					if(distance11 < distance21){
						oriAction1.addAction(action.getAction(), action.x1, action.y1, moment);
						reverse = false;
					}
					else {
						oriAction2.addAction(action.getAction(), action.x2, action.y2, moment);
						reverse = true;
					}
					
					twoPointer = true;
				}
			}
			break;
		case RawActionVO.UP:
			twoPointer = false;
			
			if(pActionList.size() == 1){
				Log.i("RecordSystem", "up1");
				PackagedRecordAction oriAction = pActionList.get(0);
				oriAction.addAction(action.getAction(), action.x1, action.y1, moment);
				
                 setResult(resultVO, oriAction);
                 
			}
			else {
				Log.i("RecordSystem", "up2");
				PackagedRecordAction oriAction1 = pActionList.get(0);
				PackagedRecordAction oriAction2 = pActionList.get(1);
				
				float distance11 = oriAction1.getDistance(action.x1, action.y1);
				float distance12 = oriAction2.getDistance(action.x1, action.y1);
				
				if(distance11 < distance12){
					oriAction1.addAction(action.getAction(), action.x1, action.y1, moment);

					 setResult(resultVO, oriAction1);
					pActionList.remove(oriAction1);
				}
				else {
					oriAction2.addAction(action.getAction(), action.x1, action.y1, moment);

					 setResult(resultVO, oriAction2);
					
					 pActionList.remove(oriAction2);
				}
			}
			
			break;
		default:
			break;
		}
		
		Log.i("RecordSystem", "resultVO"+resultVO.isSuccess());
			
		return resultVO;
	}


	public void setResult(InputResultVO resultVO, PackagedRecordAction action){
		 int kind = action.getKind();
         if(kind == LyricsAction.TAP){
        	 Log.i("RecordSystem", "TAP");
         	resultVO.setSuccess(true);
         	resultVO.setWhichPillar(action.getStartSection());
         	finishedLyricsAction.add(new LyricsAction(LyricsAction.TAP, action.getMoment(), (byte) action.getStartSection(), LyricsAction.BEGIN_POINT));
         	
         }
         else{
         	resultVO.setSuccess(true);
         	resultVO.setPoints(new int[]{action.getStartSection(),action.getEndSection()});
         	finishedLyricsAction.add(new LyricsAction(LyricsAction.DRAG, action.getStartMoment(), (byte) action.getStartSection(), LyricsAction.BEGIN_POINT));
         	finishedLyricsAction.add(new LyricsAction(LyricsAction.DRAG, action.getMoment(), (byte) action.getEndSection(), LyricsAction.END_POINT));
         }
         pActionList.remove(action);
	}
	public void reset(){
		init();
	}
	private void init(){
		//加载状态机
				pActionList = new ArrayList<PackagedRecordAction>();
				
				Log.i("RecordSystem", "状态机加载完毕！");
		
	    //
		        finishedLyricsAction=new ArrayList<LyricsAction>();
	}
	private void saveLyricsInfo(Lyrics lyrics){
		LyricsWriter writer = new LyricsWriter();
		
		try {
			writer.write(lyrics);
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}

	public int getNoteNum() {
		// TODO Auto-generated method stub
		return finishedLyricsAction.size();
	}

	public String getDuration() {
		// TODO Auto-generated method stub
		return recordingMusic.getDuration();
	}
}
